import { ActionCreatorWithPayload, ActionWithPayload } from "redux"
import { ThunkAction } from "redux-thunk"
import { authLs } from "@/utils/auth"
import { getCurrentUserInfo, getUserPhoneNumber } from "@/apis/yikao-community"
import {
  RESET,
  RECEIVESTATE,
  UPDATEUSERINFO,
  CLEARUSERINFO,
  UPDATETOKEN,
  UPDATEEXTRA
} from "../actionTypes/auth"

/**
 * reset store
 * @returns Action
 */
export const reset: ActionCreatorWithPayload<undefined> = () => {
  authLs.removeAuthInfo()
  return {
    type: RESET,
    payload: undefined
  }
}
/**
 * clear store
 * @returns Action
 */
export const clearUserInfo: ActionCreatorWithPayload<undefined> = () => {
  authLs.removeUserInfo()
  return {
    type: CLEARUSERINFO,
    payload: undefined
  }
}
/**
 * set store state fully
 * @param state full store state to be set
 * @returns Action
 */
export const receiveState: ActionCreatorWithPayload<
  Omit<IAuthStore, "extra">,
  Omit<IAuthStore, "extra">
> = (state: IAuthStore) => {
  authLs.setAuthInfo(state)
  return {
    type: RECEIVESTATE,
    payload: state
  }
}

/**
 * patch `userInfo` state
 * @param state partial userInfo state
 * @returns Action
 */
export const patchUserInfo: ActionCreatorWithPayload<
  IAuthStore["userInfo"],
  IAuthStore["userInfo"]
> = (state: IAuthStore["userInfo"]) => {
  authLs.patchUserInfo(state)
  return {
    type: UPDATEUSERINFO,
    payload: state
  }
}

/**
 * patch `extra` state
 * @param state partial extra state
 * @returns Action
 */
export const patchExtra: ActionCreatorWithPayload<IAuthStore["extra"], IAuthStore["extra"]> = (
  state: IAuthStore["extra"]
) => {
  authLs.patchExtra(state)
  return {
    type: UPDATEEXTRA,
    payload: state
  }
}

/**
 * update `token` field
 * @param token token value
 * @returns Action
 */
export const updateToken: ActionCreatorWithPayload<IAuthStore["token"], IAuthStore["token"]> = (
  token: IAuthStore["token"]
) => {
  authLs.setToken(token)
  return {
    type: UPDATETOKEN,
    payload: token
  }
}
/**
 * send a http request to fetch user info for refreshing
 * @returns Action
 */
export const refreshUserInfo = (): ThunkAction<
  Promise<any>,
  ITabbarStore,
  unknown,
  ActionWithPayload<IUserInfo[]>
> => {
  return dispatch => {
    return getCurrentUserInfo().then(res => {
      if (res.data && res.data.data) {
        dispatch(patchUserInfo(res.data.data) as any)
      }
    })
  }
}
/**
 * send a http request to fetch user info for refreshing
 * @returns Action
 */
export const loginByPhone = (
  params: IApiRelative.IGetUserPhoneNumber.IParams
): ThunkAction<Promise<any>, ITabbarStore, unknown, ActionWithPayload<IUserInfo[]>> => {
  return dispatch => {
    return getUserPhoneNumber(params).then(res => {
      if (res.data && res.data.data) {
        const { accessToken, ...userInfo } = res.data.data
        dispatch(
          receiveState({
            userInfo,
            token: accessToken
          }) as any
        )
        return userInfo
      }
    })
  }
}
